<script lang="js" setup>
import {ref, watch, onBeforeUnmount} from 'vue'
import {runQuery} from '@/services/neo4j'
import {DataSet} from 'vis-data'
import {Network} from 'vis-network'
import { useTurnStore } from '@/stores/turn'

const graphContainer = ref(null)
const network = ref(null)

const nodes=new DataSet();
const edges=new DataSet();
const idMap = new Map() // 跟踪ID和实际对象的映射

const store=useTurnStore();

const fetchChosenNodeData=async(ids)=>{
  console.log('Selected case IDs:', ids);

  if(ids.length>0){
    nodes.clear();
    edges.clear();
    idMap.clear();
    try {
      const result = await runQuery(`
        MATCH (n:Case)
        WHERE n.case_id IN [${ids.toString()}]
        WITH n
        MATCH (n)-[r]->(m)
        RETURN n, r, m
        UNION
        MATCH (n:Case)
        WHERE n.case_id IN [${ids.toString()}]
        WITH n
        MATCH (m)-[r]->(n)
        RETURN n, r, m
      `);

      console.log('Query result:', result);

      result.forEach(item => {
        try {
          // 处理起始节点
          if (item.n) {
            const nodeId = item.n.identity
            const rawLabel = item.n.properties?.name || item.n.labels[0] || '节点';

            if (!idMap.has(`node-${nodeId}`)) {
              const nodeObj = {
                id: nodeId,
                label: rawLabel.length > 10 ? rawLabel.substring(0, 8) + '..' : rawLabel,
                group: item.n.labels[0] || 'default',
                properties: item.n.properties || {},
                shortLabel: rawLabel.length > 10 ? rawLabel.substring(0, 8) + '..' : rawLabel,
              }
              nodes.add(nodeObj)
              idMap.set(`node-${nodeId}`, nodeObj)
            }
          }

          // 处理目标节点
          if (item.m) {
            const nodeId = item.m.identity
            let rawLabel = item.m.properties?.name || item.m.labels[0] || '节点';

            if(item.m.labels[0]==="OpenTime"){
              const {time:{year,month,day}}=item.m.properties;
              rawLabel=`${year}-${month}-${day}`;
            }

            if (!idMap.has(`node-${nodeId}`)) {
              const nodeObj = {
                id: nodeId,
                label: rawLabel.length > 10 ? rawLabel.substring(0, 15) + '...' : rawLabel,
                group: item.m.labels[0] || 'default',
                properties: item.m.properties || {}
              }
              nodes.add(nodeObj)
              idMap.set(`node-${nodeId}`, nodeObj)
            }
          }

          // 处理关系
          if (item.r) {
            const relId = item.r.identity
            if (!idMap.has(`rel-${relId}`)) {
              const relObj = {
                id: relId,
                from: item.r.start,
                to: item.r.end,
                label: item.r.type || 'REL',
                properties: item.r.properties || {}
              }
              // 检查关联节点是否存在
              if (idMap.has(`node-${relObj.from}`) && idMap.has(`node-${relObj.to}`)) {
                edges.add(relObj)
                idMap.set(`rel-${relId}`, relObj)
              } else {
                console.warn(`关系 ${relId} 的节点不存在，跳过添加`)
              }
            }
          }
        } catch (e) {
          console.error('处理记录时出错:', e, item)
        }
      })

      // 渲染图谱
      if (graphContainer.value) {
        const data = {nodes, edges}
        const options = {
          nodes: {
            shape: 'dot',
            size: 16,
            font: {
              size: 12,
              color: "#ffffff"
            },
            borderWidth: 2,
            borderWidthSelected: 3,
            color: {
              border: '#ffffff',
              background: '#409EFF',
              highlight: {
                border: '#ffffff',
                background: '#67C23A'
              }
            }
          },
          edges: {
            arrows: {
              to: {
                enabled: true,
                scaleFactor: 0.5,
                type: 'arrow'
              }
            },
            width: 1,
            color: {
              color: '#ffffff',
              highlight: '#67C23A',
              hover: '#67C23A'
            },
            font: {
              size: 10,
              color: '#ffffff',
              strokeWidth: 0,
              strokeColor: 'transparent'
            },
            smooth: {
              type: 'continuous'
            }
          },
          physics: {
            stabilization: {
              enabled: true,
              iterations: 1000,
              updateInterval: 25
            }
          },
          interaction: {
            hover: true,
            tooltipDelay: 200
          }
        }

        if(network.value) {
          network.value.destroy();
          network.value=null;
        }

        network.value = new Network(graphContainer.value, data, options)
        graphContainer.value.classList.add("show");
      }
    } catch (error) {
      console.error('获取数据失败:', error)
    }
  }
}

const refresh=()=>{
  store.clearChosenCaseIds();
  nodes.clear();
    edges.clear();
    idMap.clear();
}

watch(
  ()=>Array.from(store.chosenCaseIds),
  (newVal) => {
    fetchChosenNodeData(newVal);
  },
  {deep:true}
);

onBeforeUnmount(() => {
  if (network.value) {
    network.value.destroy();
  }
});

const handleDblClick = () => {
  if(store.turnData === "Neo4jExample"){
    store.turnData = ""
  }else{
    store.turnData = "Neo4jExample"
  }
}

</script>

<template>
  <div class="knowledge-graph-container" :class="{active: store.turnData === 'Neo4jExample'}">
    <div class="graph-header">
      <h4 class="graph-title">所选案件关系图谱
        <span @click="handleDblClick" style="padding-top: 10px; transition: all 1s ease;
cursor: pointer;">
        <el-icon><ArrowLeft /></el-icon><el-icon><ArrowRight /></el-icon>
      </span>
      </h4>
      <el-button type="primary" @click="refresh" circle class="refresh-btn">
        <el-icon>
          <RefreshLeft/>
        </el-icon>
      </el-button>
    </div>
    <el-divider class="graph-divider"/>
    <div class="graph-wrapper">
      <div ref="graphContainer" class="graph-canvas"></div>
      <div v-if="!store.chosenCaseIds.size" class="empty-state">
        <el-icon class="empty-icon"><DataLine /></el-icon>
        <p class="empty-text">请选择案件查看关系图谱</p>
        <p class="empty-hint">在案件列表中选择案件即可查看其关联关系</p>
      </div>
    </div>
  </div>
</template>

<style scoped lang="scss">
.knowledge-graph-container {
  width: 96%;
  height: 96%;
  margin: 5px auto;
  background-color: rgba(255, 255, 255, 0.05);
  border-radius: 8px;
  backdrop-filter: blur(8px);
  border: 1.5px solid rgba(255, 255, 255, 0.2);
  box-shadow: 0 4px 30px rgba(0, 0, 0, 0.1);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  transition: all 1s ease;
}

.graph-header {
  padding: 8px;
  padding-bottom: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 8px;
}

.graph-title {
  margin: 0;
  color: white;
  font-size: 18px;
  font-weight: 500;
}

.refresh-btn {
  background-color: rgba(255, 255, 255, 0.1);
  border: 1px solid rgba(255, 255, 255, 0.2);

  &:hover {
    background-color: rgba(255, 255, 255, 0.2);
  }
}

.graph-divider {
  margin: 0 0 8px 0;
  border-color: rgba(255, 255, 255, 0.1);
}

.graph-wrapper {
  position: relative;
  flex: 1;
  min-height: 300px;
  height: calc(100% - 60px);
  padding: 8px;
}

.graph-canvas {
  width: 100%;
  height: 100%;
  border-radius: 8px;
  overflow: hidden;
  transition: opacity 0.3s ease;

  &.show {
    opacity: 1;
  }

  &:not(.show) {
    opacity: 0;
  }
}

.empty-state {
  width: 50%;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 32px;
  background-color: rgba(255, 255, 255, 0.05);
  border-radius: 12px;
  border: 1px dashed rgba(255, 255, 255, 0.2);
}

.empty-icon {
  font-size: 48px;
  color: rgba(255, 255, 255, 0.3);
  margin-bottom: 16px;
}

.empty-text {
  margin: 0 0 8px 0;
  color: white;
  font-size: 16px;
  font-weight: 500;
}

.empty-hint {
  margin: 0;
  color: rgba(255, 255, 255, 0.6);
  font-size: 14px;
}

:deep(.vis-network) {
  canvas {
    border-radius: 8px;
  }
}

:deep(.vis-tooltip) {
  background-color: rgba(0, 0, 0, 0.8) !important;
  border: none !important;
  border-radius: 4px !important;
  padding: 8px 12px !important;
  color: white !important;
  font-size: 14px !important;
}

:deep(.vis-network-tooltip) {
  background-color: rgba(0, 0, 0, 0.8) !important;
  border: none !important;
  border-radius: 4px !important;
  padding: 8px 12px !important;
  color: white !important;
  font-size: 14px !important;
}

.active{
  height: 150vh;
  width: 60vw;
  transform: translate(35%, 20%);
  background-color: rgba(0, 0, 0, 0.5);
  z-index: 999;
  span{
    .el-icon{
      transform: rotate(180deg);
    }
  }
}
</style>
